package com.itgacl.magic4j.libcommon.component.storage.service.impl;

import cn.hutool.core.util.StrUtil;
import com.itgacl.magic4j.libcommon.component.storage.bean.UploadResult;
import com.itgacl.magic4j.libcommon.component.storage.enums.StorageTypeEnum;
import com.itgacl.magic4j.libcommon.util.FileUtil;
import com.itgacl.magic4j.libcommon.util.GUIDUtil;
import com.itgacl.magic4j.libcommon.util.MD5Util;
import com.itgacl.minio.MinioService;
import com.itgacl.minio.annotation.EnableMinio;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.http.MediaType;
import org.springframework.http.MediaTypeFactory;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@Slf4j
@ConditionalOnBean(annotation = EnableMinio.class)
@Service
public class MinioStorageServiceImpl extends BaseStorageService {

    private static final String STORAGE_TYPE = StorageTypeEnum.MINIO.getDescription();

    @Autowired
    private MinioService minioService;


    @Override
    public UploadResult uploadFile(InputStream inputStream, String fileName, String savePath) {
        UploadResult uploadResult = new UploadResult();
        uploadResult.setStorageType(STORAGE_TYPE);
        Long startTime = System.currentTimeMillis();
        try{
            uploadResult.setFileLength((long) inputStream.available());
            String ext = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();// 后缀名
            uploadResult.setOriginalFileName(fileName);
            uploadResult.setFileSuffix(ext);
            String newFileName = GUIDUtil.genRandomGUID()+"."+ext;
            uploadResult.setNewFileName(newFileName);
            //springframework提供的MediaTypeFactory工具类可以很方便的根据文件名获取contentType值
            Optional<MediaType> mediaType = MediaTypeFactory.getMediaType(fileName);
            String contentType="";
            if(mediaType.isPresent()){
                contentType = mediaType.get().toString();
            }
            if(StrUtil.isBlank(contentType)){
                contentType=MediaType.TEXT_PLAIN_VALUE;//默认
            }
            byte[] bytes = FileUtil.input2ByteArray(inputStream);
            String fileUrl = minioService.uploadFile(bytes,newFileName,contentType);//上传文件
            uploadResult.setFileUrl(fileUrl);
            //计算文件MD5
            uploadResult.setFileMd5(MD5Util.getBytesMD5(bytes));
            uploadResult.setUploadSuccess(true);
        }catch (Exception e){
            log.error(e.getMessage(),e);
            uploadResult.setUploadSuccess(false);//上传失败
        }
        Long endTime = System.currentTimeMillis();
        uploadResult.setUseTime(endTime-startTime);
        return uploadResult;
    }

    @Override
    public List<UploadResult> uploadFile(Map<String, InputStream> inputStreamMap, String savePath) {
        List<UploadResult> uploadResultList = new ArrayList<>();
        inputStreamMap.forEach((fileName,inputStream)->{
            UploadResult uploadResult = uploadFile(inputStream, fileName, savePath);
            uploadResultList.add(uploadResult);
        });
        return uploadResultList;
    }

    @Override
    public UploadResult uploadFile(File file, String savePath) {
        try {
            return uploadFile(FileUtil.file2ByteArray(file),file.getName(),savePath);
        } catch (IOException e) {
            log.error(e.getMessage(),e);
        }
        return null;
    }

    @Override
    public UploadResult uploadFile(byte[] fileByte, String fileName, String savePath) {
        UploadResult uploadResult = new UploadResult();
        uploadResult.setStorageType(STORAGE_TYPE);
        Long startTime = System.currentTimeMillis();
        try {
            uploadResult.setFileLength((long) fileByte.length);
            String ext = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();// 后缀名
            uploadResult.setOriginalFileName(fileName);
            uploadResult.setFileSuffix(ext);
            String newFileName = GUIDUtil.genRandomGUID()+"."+ext;
            uploadResult.setNewFileName(newFileName);
            //springframework提供的MediaTypeFactory工具类可以很方便的根据文件名获取contentType值
            Optional<MediaType> mediaType = MediaTypeFactory.getMediaType(fileName);
            String contentType="";
            if(mediaType.isPresent()){
                contentType = mediaType.get().toString();
            }
            if(StrUtil.isBlank(contentType)){
                contentType=MediaType.TEXT_PLAIN_VALUE;//默认
            }
            String fileUrl = minioService.uploadFile(fileByte,newFileName,contentType);
            uploadResult.setFileUrl(fileUrl);
            uploadResult.setFileMd5(MD5Util.getBytesMD5(fileByte));
            uploadResult.setUploadSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
            uploadResult.setUploadSuccess(false);//上传失败
        }
        Long endTime = System.currentTimeMillis();
        uploadResult.setUseTime(endTime-startTime);
        return uploadResult;
    }

    @Override
    public int deleteFile(String fileUrl) {
        try {
            String fileName = fileUrl.substring(fileUrl.lastIndexOf('/')+1);
            minioService.removeFile(fileName);
            return 0;
        }catch (Exception e){
            log.error(e.getMessage(),e);
            return -1;
        }
    }

    @Override
    public Map<String, Integer> deleteFile(List<String> listFileUrl) {
        Map<String, Integer> resultMap = new HashMap<>();
        for (String fileUrl : listFileUrl) {
            int retVal = deleteFile(fileUrl);
            resultMap.put(fileUrl,retVal);
        }
        return resultMap;
    }
}
